package com.github.prontera.controller;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.github.prontera.ApiVersion;
import com.github.prontera.Shift;
import com.github.prontera.StatusCode;
import com.github.prontera.common.filter.CurrentUserId;
import com.github.prontera.common.filter.IgnoreAuth;
import com.github.prontera.common.mapper.JsonMapper;
import com.github.prontera.config.ConfigUtil;
import com.github.prontera.domain.Client;
import com.github.prontera.domain.Order;
import com.github.prontera.domain.enums.DictTypeEnum;
import com.github.prontera.domain.enums.OrderTypeEnum;
import com.github.prontera.domain.enums.PayChannelEnum;
import com.github.prontera.domain.enums.PayStatusEnum2;
import com.github.prontera.domain.enums.PayTypeEnum;
import com.github.prontera.domain.enums.RealAuthStatusEnum;
import com.github.prontera.domain.enums.VipStatusEnum;
import com.github.prontera.model.PayAttach;
import com.github.prontera.model.PayBeanRequest;
import com.github.prontera.model.PayRequest;
import com.github.prontera.model.request.ProductPayRequest;
import com.github.prontera.model.response.ObjectDataResponse;
import com.github.prontera.service.ClientService;
import com.github.prontera.service.CommonDict;
import com.github.prontera.service.OrderService;
import com.github.prontera.util.PayUtil;
import com.github.prontera.util.ServletUtil;
import com.itstyle.common.utils.AddressUtils;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import me.hao0.common.date.Dates;
import me.hao0.wepay.core.Wepay;
import me.hao0.wepay.core.WepayBuilder;
import me.hao0.wepay.model.pay.AppPayResponse;

@RestController
@RequestMapping(value = ApiVersion.API_V1_PREFIX + "/pay")
public class PayController {

	private static final Logger logger = LoggerFactory.getLogger(PayController.class);

	@Autowired
	private ConfigUtil configUtil;
	@Autowired
	private ClientService clientService;
	@Autowired
	private OrderService orderService;
	
	 /**
     * 支付宝支付回调
     */
	@IgnoreAuth
	@ApiOperation(value="支付宝支付回调")
	@RequestMapping(value="alipayNotify",method=RequestMethod.POST)
	public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String  message = "success";
		Map<String, String> params = new HashMap<String, String>();
		// 取出所有参数是为了验证签名
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String parameterName = parameterNames.nextElement();
			params.put(parameterName, request.getParameter(parameterName));
		}
		//验证签名 校验签名
		boolean signVerified = false;
		
		String signType=params.get("sign_type");
		try {
			signVerified = AlipaySignature.rsaCheckV1(params,configUtil.getAliPublicKey(), "UTF-8",signType);
		} catch (AlipayApiException e) {
			e.printStackTrace();
			message =  "failed";
		}
		if (signVerified) {
			logger.info("支付宝验证签名成功！");
			// 若参数中的appid和填入的appid不相同，则为异常通知
			if (!configUtil.getAliAppId().equals(params.get("app_id"))) {
				logger.info("与付款时的appid不同，此为异常通知，应忽略！");
				message =  "failed";
			}else{
				String outtradeno = params.get("out_trade_no");
				Order findOrder=new Order();
				findOrder.setTradeNo(outtradeno);
				Order order=orderService.findOne(findOrder);// 自定义参数;
				//在数据库中查找订单号对应的订单，并将其金额与数据库中的金额对比，若对不上，也为异常通知
				String status = params.get("trade_status");
				if (status.equals("WAIT_BUYER_PAY")) { // 如果状态是正在等待用户付款
					logger.info(outtradeno + "订单的状态正在等待用户付款");
					order.setStatus(PayStatusEnum2.WAIT_PAYMENT);
				} else if (status.equals("TRADE_CLOSED")) { // 如果状态是未付款交易超时关闭，或支付完成后全额退款
					logger.info(outtradeno + "订单的状态已经关闭");
					order.setStatus(PayStatusEnum2.WAIT_PAYMENT);
				} else if (status.equals("TRADE_SUCCESS") || status.equals("TRADE_FINISHED")) { // 如果状态是已经支付成功
					logger.info("(支付宝订单号:"+outtradeno+"付款成功)");
					//这里 根据实际业务场景 做相应的操作
					if(order==null){
						message =  "failed";
					}
					String attach=order.getExtParams();// 自定义参数
					try {
						if (StringUtils.isEmpty(attach)) {
							message =  "failed";
							return;
						}
						PayAttach payAttach = JsonMapper.nonDefaultMapper().fromJson(attach, PayAttach.class);
						if (payAttach.getAmount().doubleValue() <= 0) {
							message =  "failed";
							return;
						}
						executePay(payAttach);
					} catch (Exception e) {
						e.printStackTrace();
						message =  "failed";
					}
					order.setStatus(PayStatusEnum2.SUCCESS);
				} else {
					order.setStatus(PayStatusEnum2.PAYMENT_FAIL);
				}
				orderService.updateByTradeNo(order);
			}
		} else { // 如果验证签名没有通过
			message =  "failed";
			logger.info("验证签名失败！");
		}
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(message.getBytes());
		out.flush();
		out.close();
	}
	
	/**
	 * 微信支付预下单
	 */
	
	@ResponseBody
	@ApiOperation(value = "阿里支付预调用",notes = "阿里支付预调用")
	@RequestMapping(value = "aliPrePay", method = RequestMethod.POST)
	public ObjectDataResponse<String> aliPrePay(@ApiParam(hidden=true,name="登录用户ID")@CurrentUserId Long clientId,@RequestBody ProductPayRequest productPayRequest) {
		if(productPayRequest.getTotalFee()==null||productPayRequest.getTotalFee()<0.01){
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "totalFee必传");
		}
		if(productPayRequest.getType()==null){
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "type必传");
		}
		PayAttach payAttach =new PayAttach();
		
		payAttach.setPayChannel(PayChannelEnum.ALI_PAY);
		payAttach.setAmount(new BigDecimal((productPayRequest.getTotalFee()/100.0D)));
		payAttach.setClientId(clientId);
		
		String orderNo = UUID.randomUUID().toString().replace("-", "");
		Integer totalFee =productPayRequest.getTotalFee().intValue();
		String notifyUrl = configUtil.getPayCallbackUrl()+ApiVersion.API_V1_PREFIX + "/pay/alipayNotify";// 回调接口
		
		String subject=null;
		if(productPayRequest.getType()==OrderTypeEnum.RECHARGE_BEAN){
			subject="唐豆豆充值";
			payAttach.setPayType(PayTypeEnum.RECHARGE_BEAN);
		}else if (productPayRequest.getType()==OrderTypeEnum.TALENT){
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "talendOrderId");
			}
			subject="达人支付";
			payAttach.setPayType(PayTypeEnum.TALENT);
			payAttach.setTalendOrderId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.VIP){
			subject="购买VIP";
			payAttach.setPayType(PayTypeEnum.VIP);
		}else if (productPayRequest.getType()==OrderTypeEnum.BUY_ACTIVITY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "activityId必传");
			}
			subject="参与活动";
			payAttach.setPayType(PayTypeEnum.ACTIVITY);
			payAttach.setActivityId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.ISSUE_PAY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "issueId必传");
			}
			subject="红包支付";
			payAttach.setPayType(PayTypeEnum.ISSUE_PAY);
			payAttach.setIssueId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.WECHAT_PAY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "lookClientId必传");
			}
			subject="查看微信号";
			payAttach.setPayType(PayTypeEnum.LOOK_WECHAT);
			payAttach.setLookClientId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.RECHARGE){	
			subject="余额充值";
			payAttach.setPayType(PayTypeEnum.RECHARGE);
		}else if (productPayRequest.getType()==OrderTypeEnum.TAKS_DEPOSIT_AMOUNT){	
			subject="任务保证金";
			payAttach.setPayType(PayTypeEnum.TAKS_DEPOSIT_AMOUNT);
			payAttach.setTaskId(productPayRequest.getProductId());
			payAttach.setNumber(productPayRequest.getNumber());
		}
		if(productPayRequest.getType()==OrderTypeEnum.BUY_ACTIVITY){
			Client client=clientService.get(clientId);
			if(client==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "用户未登录");
			}
			if(client.getVipStatus()!=VipStatusEnum.VIP){
				Shift.fatal(StatusCode.NOT_VIP, "请先购买VIP服务");
			}
			if(client.getRealAuthStatus()!=RealAuthStatusEnum.AUTHED){
				Shift.fatal(StatusCode.NOT_REAL_AUTH, "实名认证才能参与");
			}
		}
		//实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", configUtil.getAliAppId(), configUtil.getAliPrivateKey(), "json", "UTF-8", configUtil.getAliProjectPublicKey(), "RSA2");
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		
		model.setBody("");
		model.setSubject(subject);
		model.setOutTradeNo(orderNo);
		model.setTimeoutExpress("30m");
		model.setTotalAmount(String.valueOf((productPayRequest.getTotalFee()/100.0D)));
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(notifyUrl);
		
		String orderString=null;
		try {
	        //这里和普通的接口调用不同，使用的是sdkExecute
	        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
	        orderString=response.getBody();//就是orderString 可以直接给客户端请求，无需再做处理。
		} catch (AlipayApiException e) {
		    e.printStackTrace();
		}
		Order order=new Order();
		order.setExtParams(JsonMapper.nonDefaultMapper().toJson(payAttach));
		order.setAmount(new BigDecimal((totalFee/100.0D)));
		order.setClientId(clientId);
		order.setServiceId(productPayRequest.getProductId());
		order.setRequestParams(JsonMapper.nonDefaultMapper().toJson(model));
		order.setTradeNo(orderNo);
		order.setType(productPayRequest.getType());
		orderService.insertOrder(order);
		return new ObjectDataResponse<String>(orderString);
	}
	
	/**
	 * 微信支付预下单
	 */
	
	@ApiOperation(value = "微信支付预下单")
	@ResponseBody
	@RequestMapping(value = "wechatPrePay", method = RequestMethod.POST)
	public ObjectDataResponse<AppPayResponse> wechatPrePay(HttpServletRequest httpServletRequest,@ApiParam(hidden = true, name = "登录用户ID") @CurrentUserId Long clientId,
			@RequestBody ProductPayRequest productPayRequest) throws Exception {

		if(productPayRequest.getTotalFee()==null||productPayRequest.getTotalFee()<0.01){
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "totalFee必传");
		}
		if(productPayRequest.getType()==null){
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "type必传");
		}
		PayAttach payAttach =new PayAttach();
		
		payAttach.setPayChannel(PayChannelEnum.WECHAT);
		payAttach.setAmount(new BigDecimal((productPayRequest.getTotalFee()/100.0D)));
		payAttach.setClientId(clientId);
		
		String orderNo = UUID.randomUUID().toString().replace("-", "");
		Integer totalFee =productPayRequest.getTotalFee().intValue();
		String notifyUrl = configUtil.getPayCallbackUrl()+ApiVersion.API_V1_PREFIX + "/pay/weixinNotify";// 回调接口
		
		String subject=null;
		if(productPayRequest.getType()==OrderTypeEnum.RECHARGE_BEAN){
			subject="唐豆豆充值";
			payAttach.setPayType(PayTypeEnum.RECHARGE_BEAN);
		}else if (productPayRequest.getType()==OrderTypeEnum.TALENT){
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "talendOrderId");
			}
			subject="达人支付";
			payAttach.setPayType(PayTypeEnum.TALENT);
			payAttach.setTalendOrderId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.VIP){
			subject="购买VIP";
			payAttach.setPayType(PayTypeEnum.VIP);
		}else if (productPayRequest.getType()==OrderTypeEnum.BUY_ACTIVITY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "activityId必传");
			}
			subject="参与活动";
			payAttach.setPayType(PayTypeEnum.ACTIVITY);
			payAttach.setActivityId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.ISSUE_PAY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "issueId必传");
			}
			subject="红包支付";
			payAttach.setPayType(PayTypeEnum.ISSUE_PAY);
			payAttach.setIssueId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.WECHAT_PAY){	
			if(productPayRequest.getProductId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "lookClientId必传");
			}
			subject="查看微信号";
			payAttach.setPayType(PayTypeEnum.LOOK_WECHAT);
			payAttach.setLookClientId(productPayRequest.getProductId());
		}else if (productPayRequest.getType()==OrderTypeEnum.RECHARGE){	
			subject="余额充值";
			payAttach.setPayType(PayTypeEnum.RECHARGE);
		}else if (productPayRequest.getType()==OrderTypeEnum.TAKS_DEPOSIT_AMOUNT){	
			subject="任务保证金";
			payAttach.setPayType(PayTypeEnum.TAKS_DEPOSIT_AMOUNT);
			payAttach.setTaskId(productPayRequest.getProductId());
			payAttach.setNumber(productPayRequest.getNumber());
		}
		if(productPayRequest.getType()==OrderTypeEnum.BUY_ACTIVITY){
			Client client=clientService.get(clientId);
			if(client==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "用户未登录");
			}
			if(client.getVipStatus()!=VipStatusEnum.VIP){
				Shift.fatal(StatusCode.NOT_VIP, "请先购买VIP服务");
			}
			if(client.getRealAuthStatus()!=RealAuthStatusEnum.AUTHED){
				Shift.fatal(StatusCode.NOT_REAL_AUTH, "实名认证才能参与");
			}
		}
		// 账号信息
		String appid = configUtil.getWeichatAppid(); // appid
		String mch_id = configUtil.getWeichatMchId(); // 商业号

		Wepay wepay = WepayBuilder.newBuilder(appid, configUtil.getWeichatAppkey(), mch_id).build();

		me.hao0.wepay.model.pay.PayRequest request = new me.hao0.wepay.model.pay.PayRequest();
		request.setBody(subject);
		request.setClientId(AddressUtils.getIpAddr(httpServletRequest));
		request.setTotalFee(1);
		request.setNotifyUrl(notifyUrl);
		request.setOutTradeNo(orderNo);
		request.setTimeStart(Dates.now("yyyyMMddHHmmss"));
		AppPayResponse resp = wepay.pay().appPay(request);
		
		if(resp!=null&&!StringUtils.isEmpty(resp.getPrepayId())){
			Order order=new Order();
			order.setExtParams(JsonMapper.nonDefaultMapper().toJson(payAttach));
			order.setAmount(new BigDecimal((totalFee/100.0D)));
			order.setClientId(clientId);
			order.setServiceId(productPayRequest.getProductId());
			order.setRequestParams(JsonMapper.nonDefaultMapper().toJson(resp));
			order.setTradeNo(orderNo);
			order.setType(productPayRequest.getType());
			orderService.insertOrder(order);
		}
		return new ObjectDataResponse<AppPayResponse>(resp);
	}
    
	
	/**
	 * 处理支付宝/微信回调逻辑
	 */
	private boolean executePay(PayRequest payAttach){
		if (payAttach == null) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "payAttach不能为空!");
		}
		if (payAttach.getClientId()==null) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "clientId不能为空!");
		}
		if (payAttach.getAmount() == null || payAttach.getAmount().compareTo(new BigDecimal(0)) <= 0) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "amount不能为空!");
		}
		Long clientId =payAttach.getClientId();
		if (payAttach.getPayType() == PayTypeEnum.ACTIVITY) {// 活动
			if (payAttach.getActivityId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "activityId参数错误!");
			}
			clientService.buyActivity(clientId, payAttach.getAmount(), payAttach.getActivityId(),true);
		} else if (payAttach.getPayType() == PayTypeEnum.LOOK_WECHAT) {// 查看微信
			clientService.lookWechat(clientId, payAttach.getAmount(), payAttach.getLookClientId(),true);
		} else if (payAttach.getPayType() == PayTypeEnum.TALENT) {// 租达人
			if (payAttach.getTalentClientId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "talentClientId参数错误!");
			}
			if (payAttach.getRentId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "rentId参数错误!");
			}
			clientService.buyTalent(clientId, payAttach.getTalendOrderId(),true,payAttach.getPayChannel());
		} else if (payAttach.getPayType() == PayTypeEnum.ISSUE_PAY) {// 红包提问
			if (payAttach.getIssueId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "issueId不能为空!");
			}
			clientService.payIssue(clientId, payAttach.getAmount(),payAttach.getIssueId(), true);
		} else if (payAttach.getPayType() == PayTypeEnum.TAKS_DEPOSIT_AMOUNT) {// 任务保证金
			if (payAttach.getTaskId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "taskId不能为空!");
			}
			clientService.payTaksDepositAmount(clientId, payAttach.getAmount(), payAttach.getNumber(),payAttach.getTaskId(), true);
		}else {
			Shift.fatal(StatusCode.UNAVAILABLE_EXCEPTION, "不支持该类型操作!");
		}
		return true;
	}
	
	/**
	 * 处理支付宝/微信回调逻辑
	 */
	private boolean executePay(PayAttach payAttach) {
		if (payAttach == null) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "payAttach不能为空!");
		}
		if (payAttach.getClientId()==null) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "clientId不能为空!");
		}
		if (payAttach.getAmount() == null || payAttach.getAmount().compareTo(new BigDecimal(0)) <= 0) {
			Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "amount不能为空!");
		}
		Long clientId = payAttach.getClientId();
		if (payAttach.getPayType() == PayTypeEnum.ACTIVITY) {// 活动
			if (payAttach.getActivityId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "activityId不能为空!");
			}
			clientService.buyActivity(clientId, payAttach.getAmount(), payAttach.getActivityId(),false);
		} else if (payAttach.getPayType() == PayTypeEnum.RECHARGE_BEAN) {// 充值唐豆
			clientService.buyBean(clientId, payAttach.getAmount());
		} else if (payAttach.getPayType() == PayTypeEnum.RECHARGE) {// 余额充值
			clientService.buyRecharge(clientId, payAttach.getAmount());
		} else if (payAttach.getPayType() == PayTypeEnum.VIP) {// VIP充值
			clientService.buyVip(clientId, payAttach.getAmount());
		} else if (payAttach.getPayType() == PayTypeEnum.LOOK_WECHAT) {// 查看微信
			clientService.lookWechat(clientId, payAttach.getAmount(), payAttach.getLookClientId(),false);
		} else if (payAttach.getPayType() == PayTypeEnum.TALENT) {// 租达人
			if (payAttach.getTalendOrderId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "talendOrderId不能为空!");
			}
			clientService.buyTalent(clientId,payAttach.getTalendOrderId() ,false,payAttach.getPayChannel());
		} else if (payAttach.getPayType() == PayTypeEnum.ISSUE_PAY) {// 红包提问
			if (payAttach.getIssueId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "issueId不能为空!");
			}
			clientService.payIssue(clientId, payAttach.getAmount(),payAttach.getIssueId(), false);
		} else if (payAttach.getPayType() == PayTypeEnum.TAKS_DEPOSIT_AMOUNT) {// 红包提问
			if (payAttach.getTaskId() == null) {
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "taskId不能为空!");
			}
			clientService.payTaksDepositAmount(clientId, payAttach.getAmount(),payAttach.getNumber(),payAttach.getTaskId(), false);
		}
		return true;
	}

	/**
	 * 微信支付后台回调
	 */
	
	@IgnoreAuth
	@ApiOperation(value = "微信支付后台回调")
	@RequestMapping(value = "weixinNotify", method = RequestMethod.POST)
	public void weixinNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
		byte[] buffer = IOUtils.toByteArray(request.getInputStream());
		Map<String, String> m = PayUtil.doXMLParse(new String(buffer));
		if (m == null) {
			ServletUtil.writeText("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ", response);
		} else {
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			Iterator<String> it = m.keySet().iterator();
			while (it.hasNext()) {
				String parameter = (String) it.next();
				String parameterValue = m.get(parameter);
				String v = "";
				if (null != parameterValue) {
					v = parameterValue.trim();
				}
				packageParams.put(parameter, v);
			}
			// 判断签名是否正确
			if (PayUtil.isTenpaySign("UTF-8", packageParams, configUtil.getWeichatAppkey())) {
				logger.info("微信支付成功回调");
				if ("SUCCESS".equals(packageParams.get("result_code"))) {
					//这里 根据实际业务场景 做相应的操作
					Order findOrder=new Order();
					findOrder.setTradeNo(packageParams.get("out_trade_no"));
					Order order=orderService.findOne(findOrder);// 自定义参数;
					if(order==null){
						ServletUtil.writeJson("<xml>" + "<return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[order参数不匹配]]></return_msg></xml> ", response);
					}
					String attach=order.getExtParams();// 自定义参数
					try {
						if (StringUtils.isEmpty(attach)) {
							ServletUtil.writeJson("<xml>" + "<return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[attach参数不匹配]]></return_msg></xml> ", response);
							return;
						}
						PayAttach payAttach = JsonMapper.nonDefaultMapper().fromJson(attach, PayAttach.class);
						if (payAttach.getAmount().doubleValue() <= 0) {
							ServletUtil.writeJson("<xml>" + "<return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[amount参数不匹配]]></return_msg></xml> ", response);
							return;
						}
						executePay(payAttach);
					} catch (Exception e) {
						e.printStackTrace();
						ServletUtil.writeText("<xml>" + "<return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[attach参数不匹配]]></return_msg></xml> ",response);
					}
					// 这里是支付成功
					String orderNo = packageParams.get("out_trade_no");
					logger.info("微信订单号{}付款成功", orderNo);
					// 这里 根据实际业务场景 做相应的操作
					// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
					ServletUtil.writeText("<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml> ", response);
				} else {
					logger.info("支付失败,错误信息：{}", packageParams.get("err_code"));
					ServletUtil.writeText("<xml>" + "<return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ", response);
				}
			} else {
				logger.info("通知签名验证失败");
			}
		}
	}
	
	/**
	 * 支付后台回调
	 */
	
	@ApiOperation(value = "余额支付")
	@ResponseBody
	@RequestMapping(value = "balancePay", method = RequestMethod.POST)
	public ObjectDataResponse<Boolean> balancePay(@ApiParam(hidden=true,name="登录用户ID")@CurrentUserId Long clientId, @RequestBody PayRequest payAttach) {
		payAttach.setClientId(clientId);
		boolean success = executePay(payAttach);
		return new ObjectDataResponse<Boolean>(success);
	}
	
	/**
	 * 唐豆豆支付(查看视频,查看圈子)
	 */
	@ApiOperation(value = "唐豆豆支付(查看视频,查看圈子)")
	@ResponseBody
	@RequestMapping(value = "beanPay", method = RequestMethod.POST)
	public ObjectDataResponse<Boolean> beanPay(@ApiParam(hidden=true,name="登录用户ID")@CurrentUserId Long clientId, @RequestBody PayBeanRequest payBeanRequest) {
		if(payBeanRequest.getPayType()==PayTypeEnum.LOOK_COTERIE){//查看圈子
			BigDecimal beanCount=CommonDict.get(DictTypeEnum.LOOK_COTERIE.getDesc(), DictTypeEnum.LOOK_COTERIE.getDesc()).getValue();
			if(payBeanRequest.getCoterieId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "coterieId必传!");
			}
			clientService.lookCoterie(clientId, beanCount.intValue(), payBeanRequest.getCoterieId());
		}else if(payBeanRequest.getPayType()==PayTypeEnum.LOOK_VIDEO){//查看视频
			BigDecimal beanCount=CommonDict.get(DictTypeEnum.LOOK_VIDEO.getDesc(), DictTypeEnum.LOOK_VIDEO.getDesc()).getValue();
			if(payBeanRequest.getVideoId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "videoId必传!");
			}
			clientService.lookVideo(clientId, beanCount.intValue(), payBeanRequest.getVideoId());
		}else if(payBeanRequest.getPayType()==PayTypeEnum.TAKS_DEPOSIT_AMOUNT){//领取任务-->充值定金
			if(payBeanRequest.getTaskId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "taskId必传!");
			}
			clientService.payTaksDepositAmount(clientId, payBeanRequest.getTaskId(), payBeanRequest.getNumber());
		}else{
			Shift.fatal(StatusCode.UNAVAILABLE_EXCEPTION, "暂时不支持更多操作!");
		}
		return new ObjectDataResponse<Boolean>(true);
	}
	
	/**
	 * 唐钻支付
	 */
	@ApiOperation(value = "唐钻支付")
	@ResponseBody
	@RequestMapping(value = "diamondPay", method = RequestMethod.POST)
	public ObjectDataResponse<Boolean> diamondPay(@ApiParam(hidden=true,name="登录用户ID")@CurrentUserId Long clientId, @RequestBody PayBeanRequest payBeanRequest) {
		if(payBeanRequest.getPayType()==PayTypeEnum.TAKS_DEPOSIT_AMOUNT){//领取任务-->充值定金
			if(payBeanRequest.getTaskId()==null){
				Shift.fatal(StatusCode.INVALID_PARAMS_CONVERSION, "taskId必传!");
			}
			clientService.payTaksDepositAmount(clientId, payBeanRequest.getTaskId(), payBeanRequest.getNumber());
		}else{
			Shift.fatal(StatusCode.UNAVAILABLE_EXCEPTION, "暂时不支持更多操作!");
		}
		return new ObjectDataResponse<Boolean>(true);
	}

}
